<?php

class outboundController extends baseController {

	/** 盘亏调出 */
	public function shortage(){
		if(is_post()) { $this->save(Bound::TYPE_PK); }
		$this->display();
	}
	
	/** 需求明细列表 */
	public function demands(){
		$where = array('type='.Bound::TYPE_LL);
		
		if(UserPrivHelper::check('outbound-pickout')){
			$this->assign('hasallusers', 1);
			if($user_id=fetch_a_int('user_id')){
				$where[] = "user_id={$user_id}";
			}
		}
		else {
			$where[] = 'user_id='.UID;
		}
		$where[] = Lib::makeTimesRange();
		$where = join(' AND ', $where);
		
		$limit = PagerHelper::split2limit(OutboundHelper::count($where));
		$list  = OutboundHelper::getList($where, null, $limit[0], $limit[1]);
		$this->assign('list', $list);
		$this->display();
	}
	
	/**
	 * 领料出库，仓管使用
	 */
	public function pickout(){
		if($bound_id=fetch_a_int('id')){
			$bound = BoundHelper::getDetail($bound_id);
			if($bound['type']!=Bound::TYPE_LL){
				Show::warn("错误的出库单类型");
			}
			elseif($bound['audit_flow']!=1){
				Show::warn("领料审核失败或未审核");
			}
			elseif($bound['effect']){
				Show::warn("已出库");
			}
			
			if(is_post()){
				
				if(!($warehouse_id=fetch_a_int('warehouse_id'))){
					Show::warn("选择仓库");
				}
				if(!($warehouse = Warehouse::getName($warehouse_id))){
					Show::warn("仓库不存在");
				}
				
				Db::get()->trans()->on();
				$total = 0.0;
				foreach($bound['items'] as $item){
					
					//出库时，上期结余价格是库存价格
					$ware = Ware::getValues($item['ware_id']);
					$item['price'] = $ware['price'];
					
					//更新材料库存结余
					if(!Ware::renewValues($item, -1, $errmsg)){
						Db::get()->trans()->rollback();
						Show::warn("出库失败：{$item['name']}：{$errmsg}");
					}
					
					//完善领料明细的价值
					$ware   = Ware::getValues($item['ware_id']);
					$item['effect']		= 1;
					$item['total']		= $item['price'] * $item['amount'];
					$item['bl_amount']	= $ware['amount'];
					$item['bl_price']	= $ware['price'];
					$item['bl_total']	= $ware['total'];
					if(!BoundItems::update($bound_id, $item['ware_id'], array_intersect_key($item, 
							array_flip(array('bl_amount','bl_price','bl_total','price','total','effect'))))){
						Db::get()->trans()->rollback();
						Show::warn("更新材料{$item['name']}明细价值时出错。");
					}
					
					$total += $item['total'];
				}
				
				//完善领料出库单信息
				if(!Bound::update($bound_id, array(
					'total'	=> $total,
					'effect' => 1,
					'warehouse_id' => $warehouse_id,
					'warehouse' => $warehouse,
				))){
					Db::get()->trans()->rollback();
					Show::warn("修改领料出库单失败。");
				}
				
				Db::get()->trans()->commit();
				Show::warn("出库成功");
			}
			
			//使用当前结余库存价格做为材料价格
			$total = 0.0;
			foreach($bound['items'] as &$item){
				$ware = Ware::getValues($item['ware_id']);
				$item['price'] = $ware['price'];
				$item['total'] = floatval($item['price']) * $item['amount'];
				$total += $item['total'];
				unset($item);
			}
			$bound['total'] = $total;
			
			//todo: form ajax返回结果后，g2()没起作用。
			$this->assign('outbound', $bound);
			$this->assign('warehouses', Warehouse::getList());
			$this->display('outbound-dopickout');
//			Debug::pre($bound);
		}
		else{
			$where = array('type='.Bound::TYPE_LL);
			if($user_id=fetch_a_int('user_id')){
				$where[] = "user_id={$user_id}";
			}
			$where[] = Lib::makeTimesRange();
			$where = join(' AND ', $where);
			
			$limit = PagerHelper::split2limit(OutboundHelper::count($where));
			$list = OutboundHelper::getList($where, 'effect ASC, id DESC', $limit[0], $limit[1]);
			$this->assign('list', $list);
			$this->display();
		}
	}
	
	/** 
	 * 领料需求
	 */
	public function demand(){
		if(is_post()) {
			$amounts = fetch_a_array('amount');
			$remarks = fetch_a_array('remark');
			$add_sno = fetch_a_array('add_sno');

			$data	= array();
			foreach($amounts as $stuff_id => $amount) {
				if(empty($amount)){
					Show::warn("请填写全部材料的数量");
				}
				$ware = Ware::getbyid($stuff_id);
				if(!$ware){
					Show::warn("无此材料信息");
				}
				if(intval($amount) > $ware['amount']){
					Show::warn("材料'{$ware['name']}'的库存量不足.");
				}
				$data[$stuff_id] = array(
					'amount'	=> intval($amount),
					'remark'	=> FilterHelper::strip(fetch_a_string($stuff_id, $remarks)),
					'add_sno'	=> FilterHelper::strip(fetch_a_string($stuff_id, $add_sno)),
					'id'	=> $ware['id'],
					'name'	=> $ware['name'],
					'sno'	=> $ware['sno'],
					'brand'	=> $ware['brand'],
					'specific' => $ware['specific'],
					'unit'	=> $ware['unit'],
				);
			}

			if($data) {
				
				Db::get('Bound')->trans()->on();
				$dept_id   = UserAuthHelper::deptid();
				
				/*
				 * 修改旧记录，删除材料明细，修改记录审核状态； audit_flow/amount/total
				 * 保存并清空旧审批明细；
				 */
				$bound_id = fetch_a_int('bound_id');
				if($bound_id){ //修改
					
					$bound = $this->boundCanbeModify($bound_id);
					if(!BoundItems::deleteByBound($bound_id)){
						Db::get()->trans()->rollback();
						Show::warn('删除旧材料记录失败');
					}
					if(!Bound::update($bound_id, array(
						'audit_flow' => Reviewer::AUDIT_NONE,
						))){
							Db::get()->trans()->rollback();
							Show::warn('更新总记录失败');
					}
					if(!ReviewerHelper::backupAndClean(Reviewer::CLS_OUTDEMAND, $bound_id)){
						Db::get()->trans()->rollback();
						Show::warn('保存审批记录失败');
					}
					
				}
				else{ //添加
					
					//领料审批使用第二审批流程
					$reviewers = DeptHelper::getReviewers($dept_id, true);

					$bound_id = Bound::add(array(
						'sno'	=> Sno::cgen('outbound'),
						'flow'	=> 0,
						'class'	=> 'out',
						'type'	=> Bound::TYPE_LL,
						'addtime' => time(),
						'user_id' => UID,
						'effect' => 0,
						'reviewers' => $reviewers,
					));
					if(!$bound_id){
						Show::warn('生成领料需求记录失败');
					}
					
				}
				
				//保存材料明细
				foreach($data as $itemid=>$row){
					if(!BoundItems::add(array(
						'bound_id'	=> $bound_id,
						'class'		=> 'out',
						'ware_id'	=> $itemid,
						'sno'		=> $row['sno'],
						'name'		=> $row['name'],
						'specific'	=> $row['specific'],
						'unit'		=> $row['unit'],
						'brand'		=> $row['brand'],
						'remark'	=> $row['remark'],
						'add_sno'	=> $row['add_sno'],
						'amount'	=> $row['amount'],
						'effect'	=> 0,
						'addtime'	=> time(),
						'sum_day'	=> date('Ymd'),
					))){
						Db::get()->trans()->rollback();
						Show::warn("保存材料\"{$row['name']}\"时出错。");
					}
				}

				//增加需求审批
				if(!ReviewerHelper::expand(Reviewer::CLS_OUTDEMAND, $bound_id, $dept_id, true)){
					Db::get()->trans()->rollback();
					Show::warn("增加需求审批出错：". ReviewerHelper::getLastError());
				}
				
				Db::get()->trans()->commit();
				Show::note('保存成功，请到"需求明细"里查看审核状态', url("outbound-demands"));
				
			}
			else {
				Show::warn('请输入正确的材料信息');
			}
			
		} //end of if post()
		
		else { //修改或新增
			
			$bound_id = fetch_a_int('id');
			if($bound_id){
				$bound = $this->boundCanbeModify($bound_id);
				$items = BoundItems::getByBound($bound_id);
				$this->assign('stuffs', $items);
				$this->assign('bound', $bound);
				$this->assign('ismodify', true);
			}
			$this->display();
		}
		
	}
	
	/**
	 * 判断是否可以修改
	 */
	private function boundCanbeModify($bound_id){
		$bound = Bound::get($bound_id);
		if(!$bound){
			Show::warn('无此领料出库单');
		}
		if($bound['type']!=Bound::TYPE_LL){
			Show::warn('非领料出库单据');
		}
		if($bound['user_id']!=UID){
			Show::warn('只创建者有权修改需求记录');
		}
		if($bound['audit_flow']!=Reviewer::AUDIT_FAIL){
			Show::warn('无法修改');
		}
		return $bound;
	}
	
	/** 保存出库信息 */
	protected function save($type){
		if(!fetch_a_int('warehouse_id')){
			Show::warn('请选择仓库');
		}
		
		$amounts = fetch_a_array('amount');
		$remarks = fetch_a_array('remark');

		$data	= array();
		$total	= 0.0;
		foreach($amounts as $stuff_id => $amount) {
			if(empty($amount)){
				Show::warn("请填写全部材料的数量");
			}
			$ware = Ware::getbyid($stuff_id);
			if(!$ware){
				Show::warn("无此材料信息");
			}
			if(intval($amount) > $ware['amount']){
				Show::warn("材料'{$ware['name']}'的库存量不足.");
			}
			$data[$stuff_id] = array(
				'amount'	=> intval($amount),
				'price'		=> $ware['price'], //出库使用库存的价格
				'remark'	=> FilterHelper::strip(fetch_a_string($stuff_id, $remarks)),
				'id'	=> $ware['id'],
				'name'	=> $ware['name'],
				'sno'	=> $ware['sno'],
				'brand'	=> $ware['brand'],
				'specific' => $ware['specific'],
				'unit'	=> $ware['unit'],
			);
			$total += ($data[$stuff_id]['amount'] * $data[$stuff_id]['price']);
		}

		if($data) {
			Db::get('Bound')->trans()->on();
			
			$boundid = Bound::add(array(
				'sno'	=> Sno::cgen('outbound'),
				'flow'	=> 0,
				'class'	=> 'out',
				'type'	=> $type,
				'total' => $total,
				'addtime' => time(),
				'user_id' => UID,
				'effect' => 1,
				'warehouse_id' => fetch_a_int('warehouse_id'),
				'warehouse' => Warehouse::getName(fetch_a_int('warehouse_id')),
			));
			if(!$boundid){
				Show::warn('生成出库记录失败');
			}
			
			foreach($data as $itemid=>$row){

				//更新材料库存价值
				$ware = Db::get('Ware')->select('amount,price,amount*price AS total')->where(array('id'=>$itemid))->getOne();
				$ware['amount'] -= $row['amount'];
				$ware['total']  -= intval($row['amount']) * $row['price'];
//				$ware['price']  = $ware['total'] / $ware['amount'];
				Db::get('Ware')->update($ware)->where(array('id'=>$itemid))->exec();
				if(!Db::get('Ware')->affectedRows()){
					Db::get()->trans()->rollback();
					Show::warn("修改材料\"{$row['name']}\"的结存信息时出错。");
				}

				//保存出库明细
				if(!BoundItems::add(array(
					'bound_id'	=> $boundid,
					'class'		=> 'out',
					'ware_id'	=> $itemid,
					'sno'		=> $row['sno'],
					'name'		=> $row['name'],
					'specific'	=> $row['specific'],
					'unit'		=> $row['unit'],
					'brand'		=> $row['brand'],
					'remark'	=> $row['remark'],
					'amount'	=> $row['amount'],
					'price'		=> $row['price'],
					'total'		=> intval($row['amount']) * $row['price'],
					'effect'	=> 1,
					'addtime'	=> time(),
					'sum_day'	=> date('Ymd'),
					'bl_amount'	=> $ware['amount'],
					'bl_price'	=> $ware['price'],
					'bl_total'	=> $ware['total'],
				))){
					Db::get()->trans()->rollback();
					Show::warn("保存材料\"{$row['name']}\"时出错。");
				}

			}

			Db::get()->trans()->commit();
			
			Show::note('保存成功');
		}
		else {
			Show::warn('请输入正确的材料信息');
		}
		
	}
	
	public function view(){
		$outbound = BoundHelper::getDetail(fetch_a_int('id'));
		if(!$outbound){
			Show::warn('无此出库记录');
		}
//		Debug::pre($outbound);
		$this->assign('outbound', $outbound);
		$this->assign('reviewers', ReviewerHelper::getList(Reviewer::CLS_OUTDEMAND, fetch_a_int('id')));
		$this->assign('reviewer_back', ReviewerHelper::getBackups(Reviewer::CLS_OUTDEMAND, fetch_a_int('id')));
		$this->display();
	}
	
	public function detail(){
		$where = "class='out' AND effect=1";
		
		$from = intval(str_replace('-','',fetch_a_string('from')));
		$to   = intval(str_replace('-','',fetch_a_string('to')));
		if($from || $to){
			if(!$from) $from = '20110101';
			if(!$to) $to = date('Ymd');
			$where .= " AND sum_day >= {$from} AND sum_day <= {$to}";
		}
		if($type=fetch_a_int('type')){
			$where .= " AND type={$type}";
		}
		if($sno=fetch_a_string('sno')){
			$where .= " AND bound_sno LIKE '{$sno}%'";
		}
                if($key=fetch_a_string('key')){
			$fields = array('sno','name','specific','unit','brand','remark');
			$GLOBALS['S_KEY'] = $key;
			$func = function($v){ return "`{$v}` LIKE '%{$GLOBALS['S_KEY']}%'"; };
			$where .= ' AND ('. join(' OR ', array_map($func, $fields)). ')';
		}
		
		$page = PagerHelper::split2limit(BoundHelper::getItemsCount($where));
		$list = BoundHelper::getItemsList($where,'',$page[0],$page[1]);
//		Debug::pre($list);
		$this->assign('list', $list);
		$this->assign('types', BoundHelper::getOutTypes());
		$this->display();
	}
	
	
}

?>
